

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>Rework &mdash; PAGE 4.3 documentation</title>
    
    <link rel="stylesheet" href="_static/default.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '',
        VERSION:     '4.3',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/underscore.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    <link rel="top" title="PAGE 4.3 documentation" href="index.html" />
    <link rel="next" title="Creating and Saving Code Modules" href="saving.html" />
    <link rel="prev" title="Using PAGE" href="use.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="saving.html" title="Creating and Saving Code Modules"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="use.html" title="Using PAGE"
             accesskey="P">previous</a> |</li>
        <li><a href="index.html">PAGE 4.3 documentation</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="rework">
<span id="id1"></span><h1>Rework<a class="headerlink" href="#rework" title="Permalink to this headline">¶</a></h1>
<p>With version 4.2, I turned my attention to facilitating rework in
PAGE.  That is, how do you use PAGE to tweak the GUI without loosing
the supporting code that you have written? At the same time I want to
allow one to view the changes with the run command button in the
Python console.</p>
<p>Here is the situation.  You design a GUI and generate the Python code
using PAGE, which creates skeleton functions.  You then fleshed out
the skeleton functions to support the GUI and then decided to modify
the GUI.  If then you again generate the Python code for the GUI, you
do not want to loose the application code which you have written to
realize the application.  This is the rework problem: How to keep your
hard fought code when reworking the GUI?</p>
<p>Starting with version 4.2, I have tried to separate as completely as
possible the automatically generated GUI code from the added support
code.  My approach is to create the generated GUI code in one Python
module and the supporting code including skeleton functions and Tk
variables in a separate Python module to be imported by the GUI
module.  That is, now PAGE generates two Python modules, one for the
GUI and one for the supporting code complete with the necessary
linkage.</p>
<p>PAGE implements this schema as follows.  PAGE now works with three
files:</p>
<ul class="simple">
<li>&#8220;&lt;name&gt;.tcl&#8221; which is the design description of the GUI suitable for input to PAGE. It can either be created in PAGE, passed to PAGE as a parameter, or opened from the File submenu of the main menu.</li>
<li>&#8220;&lt;name&gt;.py&#8221; which is the main python module generated by PAGE which contains the automatically code to create the GUI on the screen. It is meant to be completely generated by PAGE. This will be referred to as the GUI module.</li>
<li>&#8220;&lt;name&gt;_support.py&#8221; which contains the code supporting the GUI module. PAGE creates a skeleton of this module that contains all of the necessary boiler plate code for linkage to the GUI module as well as the definitions of the Tk variables and skeleton versions of callback routines.  I will be referring to this as the support module.</li>
</ul>
<p>It is expected that the user will generate a new version of the GUI
module whenever he modifies the GUI but will need to modify the
support module only when new Tk variables or callback functions are
defined. The first will be much more frequent than the
latter. Further, version 4.3 provides a mechanism for updating the
support module by adding the new Tk variables and callback functions
skeletons to an existing support module.</p>
<p>In the above, &#8220;&lt;name&gt;&#8221; is the application name (it was called the
project name in the original Visual Tcl program) selected by the user
when the system saves the &#8221;.tcl&#8221; or extracted from the file name which
may be supplied as a parameter when invoking PAGE.</p>
<p>Generation of either Python module will attempt to save the tcl file
and in so doing may ask if you really want to save it. If you do not
answer &#8220;yes&#8221; the root file name may not be known and bad code could be
generated.</p>
<p>Let me repeat: You should only generate the support module once for an
application; otherwise any code which you manually added will be lost.
Well, just in case you do that inadvertently, PAGE will save some
previous versions as backups.  If you add new or change widgets in the
GUI or modify callback functions or Tk variables changes will have to be
made to the support module.</p>
<p>When saving the support module PAGE will test to see if a support
module with the same name exists and if it does, it will question the
user as to whether he wishes to continue.</p>
<p>For an example of the separation of the GUI module from the support
module, see the WCPE directory in the examples directory.  This is a
program that displays the program of WCPE which is one of my favorite
classical music stations.  In this example all of the functional code
is located in WCPE_support.py and the GUI design is recorded in WCPE.py
which is the main module.  I found it very tricky to deal with time
zones and did not want to loose any of that code and have to redo it
or to deal with diff&#8217;s ; at the same time, I was constantly tweaking
the GUI.  I generated the import module once and proceeded fill out
the init function and the callback functions in WCPE_support.py while
tweaking the GUI, i.e., changing its location, color, the size of the
display fields, etc..</p>
<p>Also, in the examples directory, you can compare the progress_bar
and the rework_progress_bar.  The directory rework_progress_bar
contains the changes that I made to the files in progress_bar to
conform to the new rework scheme. It may be instructive in that it
exemplifies an application comprised of two top level windows where
one of the windows accesses Tkinter variables in the second window.</p>
<p>With chagrin, I apologize to the PAGE users for not having thought of
this solution to rework long ago.  Even though I have tested the idea
with several examples, some of which are included in the section on
examples, I worry that I have overlooked something big.  So if you
find any problems or oversights, please let me know.</p>
<div class="section" id="automatically-updating-the-support-module">
<h2>Automatically Updating the Support Module<a class="headerlink" href="#automatically-updating-the-support-module" title="Permalink to this headline">¶</a></h2>
<p>The is the new feature of PAGE introduced with version 4.3.  The basic
idea is that reworking the GUI design may introduce new callback
functions or Tk variables which need to incorporated into the support
module. PAGE can now add those entities to the support module.  That
is, new skeletal functions are added and new entries are added to the
set_Tk_var function, if necessary a set_Tk_var is added.</p>
<p>If Control-I was selected, then the user will be given the options of:</p>
<ul class="simple">
<li>generating the support module anew,</li>
<li>using an existing support module, thereby utilizing the existing handwritten code,</li>
<li>updating an existing support module to preserve the existing code and adding new Tk Variables or Callback functions.</li>
</ul>
<p>To rephrase the above, when the user selects Gen_Python-&gt;Generate
Support Module from the main menu or selects Control-I, PAGE will
analyze an existing support module and compare the callback functions
and Tk variables in it with those utilized in the reworked design.  If
new entities are required the user will be given the option of
automatically adding them.  Existing code is not removed or modified.
It is up to the user to remove or otherwise deal with code no longer
needed.</p>
</div>
</div>
<div class="section" id="saving-of-modules">
<h1>Saving of Modules<a class="headerlink" href="#saving-of-modules" title="Permalink to this headline">¶</a></h1>
<p>One possibly confusing aspect of PAGE is the saving of the three files
associated with a PAGE GUI:</p>
<ul class="simple">
<li>The tcl file which is the input to the &#8220;working&#8221; or &#8220;design&#8221; file of PAGE.</li>
<li>The Python code generated defining the GUI object.</li>
<li>The Python support file containing much of the boiler plate and skeleton functions.</li>
</ul>
<p>PAGE implements several mechanisms for saving these files as discussed below.</p>
<p>As stated elsewhere the root name is derived from the name of the tcl
file. The Python GUI design file root name is the same as that of the
tcl file and the Python support module is that root name concatenated
with &#8220;_support&#8221;.</p>
<p>When either the Python GUI module or the support module are saved,
existing modules are retained as backups. Up to five backup modules
are retained to help avoid inadvertent lose of application code.</p>
<p>Code from the Python Console source window is not automatically saved,
the user must select either the Save or Run button of the Python
Console.</p>
<div class="section" id="save-command-in-the-menu">
<h2>Save Command in the Menu<a class="headerlink" href="#save-command-in-the-menu" title="Permalink to this headline">¶</a></h2>
<p>When File-&gt;Save or File-&gt;Save As is selected then the tcl file is
saved provided the GUI has changed since the last save action or the
loading of an existing GUI file. The previous version of the tcl file
is made a backup file.  It does not save either the GUI module or the
support module.</p>
</div>
<div class="section" id="save-button-in-the-python-console">
<h2>Save Button in the Python Console<a class="headerlink" href="#save-button-in-the-python-console" title="Permalink to this headline">¶</a></h2>
<p>When the Save button in the Console file is selected, the tcl file is
saved as above if there has been a change to GUI. Also, the content of
the top window of the Python Console is saved if it is different from
the last version of the code that was saved.  That is, if the Python
console contains GUI code then the GUI module will be saved if it has
been modified since the last save of the GUI code in the current PAGE
invocation.</p>
<p>Similarly for the case of the support module being in the
Python Console, if:</p>
<ul class="simple">
<li>the user had generated a new version of the support module,</li>
<li>had the user upgraded the support module,</li>
<li>the user had elected to use the existing support module and had modified it by editing the source window.</li>
</ul>
<p>then support module will be saved and existing support modules will be
renamed and retained as backup files.</p>
</div>
<div class="section" id="run-button-in-the-python-console">
<h2>Run Button in the Python Console<a class="headerlink" href="#run-button-in-the-python-console" title="Permalink to this headline">¶</a></h2>
<p>When the Run button is selected the code in the Python Console will be
saved if it differs from the last save in the current invocation of
PAGE. If the code in the source window is GUI code it saved as the GUI
module subject to the rules above; if it is support code it will be
saved as the support module as above.</p>
<p>Then the GUI module is execute by invoking the Python Interpreter
against the saved GUI .  Running the Python GUI code will show the
actual GUI.  Obviously it will fail if there is no support module. I
don&#8217;t think it makes sense to try executing the support module from
the Python Console because there are much better venues for debugging
the support code.</p>
<p>The save logic which I have implemented is fairly complex; I have included
below the code which is part of PAGE.</p>
<div class="highlight-python"><pre>proc vTcl:test_file_content {filename new_content} {
    # Function to determine if we can safely skip the save function.
    # A return value of 0 means that we can skip the actual save.
    # A return value of 1 means that we must save.
    global vTcl
    set save 1
    set skip 0
    # If the Python file does not exist, we clearly have to save it.
    if {[file exists $filename] == 0} {
        return $save
    }
    # If we have edited the Python Console code window, we have to save.
    set modified [$vTcl(code_window) edit modified]
    if {$modified} {
        return $save
    }
    # If the content of the code window is unchanged, we can skip the save.
    if {$new_content == $vTcl(last_save,$vTcl(python_module))} {
        return $skip     ;# Skip the save.
    }
    # If we got this far then we want to save.
    return $save     ;# Do the save.

}</pre>
</div>
<p>Note that every time that the Python code for either the GUI or the
support module is generated the new module will include a current
timestamp and so comparing will two generations will always differ if
only in the timestamps. Without the timestamps I could probably reduce
the number of saves and backup files, but I think the timestamps are
very valuable.</p>
</div>
<div class="section" id="automatic-save-at-page-exit">
<h2>Automatic Save at PAGE Exit<a class="headerlink" href="#automatic-save-at-page-exit" title="Permalink to this headline">¶</a></h2>
<p>When PAGE is closed by either Quit, Control-Q, or Control-C, the save
action is the same as for the File-&gt;Save. Again, the GUI module and
the support module are not affected.</p>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
  <h3><a href="index.html">Table Of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Rework</a><ul>
<li><a class="reference internal" href="#automatically-updating-the-support-module">Automatically Updating the Support Module</a></li>
</ul>
</li>
<li><a class="reference internal" href="#saving-of-modules">Saving of Modules</a><ul>
<li><a class="reference internal" href="#save-command-in-the-menu">Save Command in the Menu</a></li>
<li><a class="reference internal" href="#save-button-in-the-python-console">Save Button in the Python Console</a></li>
<li><a class="reference internal" href="#run-button-in-the-python-console">Run Button in the Python Console</a></li>
<li><a class="reference internal" href="#automatic-save-at-page-exit">Automatic Save at PAGE Exit</a></li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="use.html"
                        title="previous chapter">Using PAGE</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="saving.html"
                        title="next chapter">Creating and Saving Code Modules</a></p>
  <h3>This Page</h3>
  <ul class="this-page-menu">
    <li><a href="_sources/rework.txt"
           rel="nofollow">Show Source</a></li>
  </ul>
<div id="searchbox" style="display: none">
  <h3>Quick search</h3>
    <form class="search" action="search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    <p class="searchtip" style="font-size: 90%">
    Enter search terms or a module, class or function name.
    </p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="saving.html" title="Creating and Saving Code Modules"
             >next</a> |</li>
        <li class="right" >
          <a href="use.html" title="Using PAGE"
             >previous</a> |</li>
        <li><a href="index.html">PAGE 4.3 documentation</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
        &copy; Copyright 2008 - 2014 Donald Rozenberg.
      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
    </div>
  </body>
</html>